package com.wpx.log.core;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import com.wpx.log.core.annotation.OpLog;
import com.wpx.log.util.Utils;

public class LogRequestContext {
	
	private HttpServletRequest httpServletRequest;
	
	private Long statrtTime;

	private Throwable exception;
	
	private Object returnObj;
	
	private Object old;
	
	private Object nnew;
	
	private Method method;
	
	private String ip;
	
	private boolean ipPass = true;
	
	private OpLog opLogAnnotationAsTarget;
	
	private OpLog opLogAnnotationAsMethod;
	
	private ProceedingJoinPoint point;
	
	private Map<String, Object> attributes = new HashMap<String, Object>();
	
	private static LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
	
	
	
	
	public Object getOld() {
		return old;
	}

	public void setOld(Object old) {
		this.old = old;
	}

	public LogRequestContext(HttpServletRequest request, ProceedingJoinPoint point) {
		super();
		this.httpServletRequest = request;
		this.statrtTime = System.currentTimeMillis();
		this.point = point;
		this.method = ((MethodSignature)point.getSignature()).getMethod();
		this.opLogAnnotationAsMethod = this.method.getAnnotation(OpLog.class);
		this.opLogAnnotationAsTarget = point.getTarget().getClass().getAnnotation(OpLog.class);
		
	}

	
	/**
	 * 解析 el表达式的参数值
	 */
	public String parseArgsExpression(String expressionString) {
		StandardEvaluationContext context = new StandardEvaluationContext();
		String[] params = discoverer.getParameterNames(this.method);
				
		Object[] args = this.point.getArgs();
		for (int i = 0; i < args.length; i++) {
			context.setVariable(params[i], args[i]);
		}
		return Utils.getValue(context, expressionString, false ,String.class);
	}
	
	
	
	
	
	
	public HttpServletRequest getHttpServletRequest() {
		return httpServletRequest;
	}

	public Long getStatrtTime() {
		return statrtTime;
	}

	public Throwable getException() {
		return exception;
	}

	public void setException(Throwable exception) {
		this.exception = exception;
	}

	public Method getMethod() {
		return method;
	}

	public OpLog getOpLogAnnotationAsTarget() {
		return this.opLogAnnotationAsTarget;
	}
	
	public OpLog getOpLogAnnotationAsMethod() {
		return this.opLogAnnotationAsMethod;
	}
	
	public ProceedingJoinPoint getPoint() {
		return point;
	}
	public Object getNnew() {
		return nnew;
	}

	public void setNnew(Object nnew) {
		this.nnew = nnew;
	}
	
	public Object getReturnObj() {
		return returnObj;
	}

	public void setReturnObj(Object returnObj) {
		this.returnObj = returnObj;
	}

	public void setAttribute(String name, Object value) {
		this.attributes.put(name, value);
	}
	
	public Object getAttribute(String name) {
		return this.attributes.get(name);
	}

	public String getIp() {
		if(this.ip == null) {
			this.ip = Utils.getRequestIp(getHttpServletRequest());
		}
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public boolean isIpPass() {
		return ipPass;
	}

	public void setIpPass(boolean ipPass) {
		this.ipPass = ipPass;
	}
	
	
}
